package com.example.demo.pattern.iteratorpattern;

import java.util.Iterator;
import java.util.Stack;
import java.util.function.Consumer;

/**
 * 从外部使用来看，本类和普通迭代器一样，while(hasNext)，并使用next()元素，但内部实现比较不同
 */
public class CompositeIterator implements Iterator<MenuComponent> {

    /**
     * 用Stack暂存树状数据的递归打开。利用后入先出的数据遍历方式，很适合树状遍历时，先一路往下找到叶节点，再一层层遍历返回
     * 实际使用时，如果是普通item则正常next()，如果是listItem则会将其iterator push进stack，然后通过“后入先出”，遍历完该iterator再继续上层遍历
     */
    private final Stack<Iterator<MenuComponent>> stack = new Stack<Iterator<MenuComponent>>();

    public CompositeIterator(Iterator<MenuComponent> iterator) {
        stack.push(iterator);
    }

    /**
     * 实际是判断
     */
    @Override
    public boolean hasNext() {
        if (stack.isEmpty()) {
            return false;
        }
        Iterator<MenuComponent> iterator = stack.peek();
        //如果这个iterator遍历完了，就弹出，继续递归判断下一个
        if (!iterator.hasNext()) {
            stack.pop();
            return hasNext();//递归判断是否有元素
        }
        return true;
    }


    @Override
    public MenuComponent next() {
        Iterator<MenuComponent> peek = stack.peek();
        MenuComponent nextMenu = peek.next();
        if (nextMenu instanceof Menu) {//说明是menuList
            stack.push(nextMenu.iterator());
        }
        return nextMenu;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }


    @Override
    public void forEachRemaining(Consumer action) {
        throw new UnsupportedOperationException();
    }
}
